﻿import mx.events.EventDispatcher;

/* Ampliación de mx.events.EventDispatcher, tal que:
 * - Separa la lógica de difusión de eventos en un objeto a parte.
 * - Puede ser aplicado a objetos MovieClip (¿EventDispatcher no?).
 * - Permite al usuario elegir la función que va a manejar el evento
 * (EventDispatcher requiere que la función tenga el mismo nombre que el
 * evento que detecta, ej.: "evento_A" -> function evento_A() ).
 */
class EventDispatcherWrapper {
	private var extraListeners:Array;
	
	// auxiliary to not to get a compiler error.
	private var EventDispatcherWrapper_ref:EventDispatcherWrapper;
	
	// alias
	public static var wrap:Function = aplicar;
	
	public static function aplicar(receptor:Object):Object {
		var temp:EventDispatcherWrapper = new EventDispatcherWrapper(receptor);
		return receptor;
	}
	
	public function EventDispatcherWrapper(receptor:Object) {
		EventDispatcher.initialize(this);
		
		receptor.EventDispatcherWrapper_ref = this;
		receptor.EventDispatcherWrapper_ref.extraListeners = new Array();
		receptor.addEventListener = this.addEventListenerClip;
		receptor.addEventListener2 = this.addEventListenerClip2;
		receptor.removeEventListener = this.removeEventListenerClip;
		receptor.removeEventListener2 = this.removeEventListenerClip2;
		receptor.dispatchEvent = this.dispatchEventClip;
	}
	
	private function addEventListenerClip2(evt_type:String, detector:Object, callback_function:String):Void {
		EventDispatcherWrapper_ref.extraListeners.push({evt_type: evt_type, detector: detector, callback_function: callback_function});
	}
	
	private function addEventListenerClip(evt_type:String, detector:Object):Void {
		//trace("addEventListenerButton: " + this["eventDispatcher_nroSec"].addEventListener);
		EventDispatcherWrapper_ref.addEventListener(evt_type, detector);
	}

	/* Como addEventListener, salvo que permite al usuario elegir el nombre de la
	 * función detectora del evento.
	 */
	private function removeEventListenerClip2(evt_type:String, detector:Object, callback_function:String):Void {
		var k:Number = 0;
		with(EventDispatcherWrapper_ref) {
			while(k < extraListeners.length) {
				if(extraListeners[k].evt_type==evt_type && extraListeners[k].detector==detector && extraListeners[k].callback_function==callback_function) {
					extraListeners.splice(k, 1);
				}
				else {
					k++;
				}
			}
		}
	}
	
	private function removeEventListenerClip(evt_type:String, detector:Object):Void {
		EventDispatcherWrapper_ref.removeEventListener(evt_type, detector);
	}
	
	private function dispatchEventClip(evt:Object):Void {
		EventDispatcherWrapper_ref.dispatchEvent(evt);
		
		/*
		for(var k in EventDispatcherWrapper_ref.extraListeners) {
			if(EventDispatcherWrapper_ref.extraListeners[k].evt_type==evt.type)
				EventDispatcherWrapper_ref.extraListeners[k].detector[EventDispatcherWrapper_ref.extraListeners[k].callback_function](evt);
		}
		*/
		with(EventDispatcherWrapper_ref) {
			for(var k in extraListeners) {
				if(extraListeners[k].evt_type==evt.type)
					extraListeners[k].detector[extraListeners[k].callback_function](evt);
			}
		}
	}
	
	function addEventListener() {
	}
	
	function removeEventListener() {
	}
	
	function dispatchEvent() {
	}
}